package com.ansion.utils;

import android.text.TextUtils;

import com.ansion.log.VLog;
import com.google.gson.Gson;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonPrimitive;
import com.google.gson.JsonSyntaxException;
import com.google.gson.reflect.TypeToken;

import org.json.JSONObject;

import java.io.Reader;
import java.io.StringReader;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * author : sibei.chen
 * date   : 2019/8/312:06 AM
 * desc   :
 * version: 1.0
 */
public class GsonUtil {

    public static Gson gson = null;

    static {
        if (gson == null) {
            gson = new Gson();
        }
    }

    private GsonUtil() {
    }

    /**
     * 转成json
     *
     * @param object
     * @return
     */
    public static String GsonString(Object object) {
        String gsonString = null;
        if (gson != null) {
            gsonString = gson.toJson(object);
        }
        return gsonString;
    }

    /**
     * 转成bean
     *
     * @param gsonString
     * @param cls
     * @return
     */
    public static <T> T GsonToBean(String gsonString, Class<T> cls) {
        T t = null;
        if (gson != null) {
            t = gson.fromJson(gsonString, cls);
        }
        return t;
    }

    public static <T> ArrayList<T> jsonToArrayList(String json, Class<T> clazz) {
        if (gson == null) {
            gson = new Gson();
        }
        Type type = new TypeToken<ArrayList<JsonObject>>() {
        }.getType();
        ArrayList<JsonObject> jsonObjects = gson.fromJson(json, type);
        ArrayList<T> arrayList = new ArrayList<T>();
        for (JsonObject jsonObject : jsonObjects) {
            arrayList.add(gson.fromJson(jsonObject, clazz));
        }
        return arrayList;
    }

    /**
     * 转成list中有map的
     *
     * @param gsonString
     * @return
     */
    public static <T> List<Map<String, T>> GsonToListMaps(String gsonString) {
        List<Map<String, T>> list = null;
        if (gson != null) {
            list = gson.fromJson(gsonString,
                    new TypeToken<List<Map<String, T>>>() {
                    }.getType());
        }
        return list;
    }

    /**
     * 转成map
     *
     * @param gsonString
     * @return
     */
    public static <T> Map<String, T> GsonToBeanMaps(String gsonString, Class<T> cls) {
        Map<String, T> map = new HashMap<>();
        if (gson != null) {
            Map<String, JsonObject> jsonObjectMap = gson.fromJson(gsonString, new TypeToken<Map<String, JsonObject>>() {
            }.getType());

            for (String key : jsonObjectMap.keySet()) {
                map.put(key, GsonToBean(jsonObjectMap.get(key).toString(), cls));
            }
        }
        return map;
    }


    /**
     * 转成map的
     *
     * @param gsonString
     * @return
     */
    public static <T> Map<String, T> GsonToMaps(String gsonString, Class<T> valueType) {
        Map<String, T> map = null;
        if (gson != null) {
            Type type = TypeToken.getParameterized(Map.class, String.class, valueType).getType();
            map = gson.fromJson(gsonString, type);
        }
        return map;
    }



    public static <T> T parse(String json, Class<T> clazz) {
        if (TextUtils.isEmpty(json)) return null;
        try{
            return gson.fromJson(json, clazz);
        } catch (Throwable t){
            VLog.w("GroupCallBlob", t.getMessage());
            return null;
        }
    }

    public static <T> T fromJson(String jsonString, Class<T> typeOfT){
        return parse(jsonString, typeOfT);
    }

    public static <T> T fromJson(JSONObject jsonObj, Class<T> typeOfT){
        if(null==jsonObj){
            return null;
        }
        return parse(jsonObj.toString(),typeOfT);
    }

    public static <T> T fromJson(String json, Type typeOfT) throws JsonSyntaxException {//这行代码是从Gson代码中摘出来的
        if (json == null) {
            return null;
        } else {
            StringReader reader = new StringReader(json);
            T target = gson.fromJson((Reader)reader, (Type)typeOfT);
            return target;
        }
    }

    /**
     * jsonToArrayList 不支持java的基本类型的数据
     * 是对jsonToArrayList的补充
     * 非java基本数据类型jsonToList和jsonToArrayList效果是一样的
     */
    public static <T> List<T> jsonToList(String json, Class<T> clazz) {
        if (TextUtils.isEmpty(json)) {
            return new ArrayList<T>();
        }
        Type listType = TypeToken.getParameterized(List.class, clazz).getType();

        // 将JSON字符串转换为List<Long>
        if (gson == null){
            gson = new Gson();
        }
        return gson.fromJson(json, listType);
    }


    public static  <T> String toJson(T obj){
        return GsonString(obj);
    }

    public static String stringify(Object obj) {
        return gson.toJson(obj);
    }

    public static JsonElement toJsonTree(Object obj) {
        return gson.toJsonTree(obj);
    }

    public static <T> String stringify(Object obj, Class<T> clazz) {
        return gson.toJson(obj, clazz);
    }

    public static boolean isJsonValid(String json) {
        try {
            JsonElement obj = gson.toJsonTree(json);
            return true;
        } catch (Exception ignore) {
            return false;
        }
    }

    public static <T> JsonElement toJsonData(T result) {
        JsonObject json = new JsonObject();
        if (result != null) json.add("data", toJsonTree(result));
        return json;
    }


    public static JsonElement toJsonError(Throwable t) {
        JsonObject json = new JsonObject();
        String msg = t.getClass().getSimpleName() + ", " + t.getMessage();
        json.add("error", new JsonPrimitive(msg));
        return json;
    }


    public static Gson getGson(){
        return gson;
    }
}
